#include "widget.h"
#include<QFont>
#include<QGridLayout>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    display=new QLineEdit("0");
    display->setReadOnly(true);
    display->setAlignment(Qt::AlignRight);
    display->setMaxLength(15);

    QFont font=display->font();
    font.setPointSize(font.pointSize()+8);
    display->setFont(font);

    for(int i=0;i<10;i++)
    {
        digitButtons[i]=createButton(QString::number(i),SLOT(digitClicke()));
    }

    Button*pointBtn=createButton(".",SLOT(pointClicked()));
    Button*backspaceBtn=createButton("BackSpace",SLOT(backSpaceClicked()));
    Button*clearBtn=createButton("clear",SLOT(clear()));
    Button*clearAllBtn=createButton("clear all",SLOT(clearAll()));

    Button*divBtn=createButton("\303\267",SLOT(muliplicativeOperatorClicked()));//除号的编码
    Button*timesBtn=createButton("\303\227",SLOT(muliplicativeOperatorClicked()));//乘号的编码

    Button*minusBtn=createButton("-",SLOT(additiveOperatorClicked()));//
    Button*plusBtn=createButton("+",SLOT(additiveOperatorClicked()));//

    Button*sqrtBtn=createButton("sqrt",SLOT(unaryOperatorClicked()));//
    Button*powerBtn=createButton("x\302\262",SLOT(unaryOperatorClicked()));//平方的编码
    Button*reciprocalBtn=createButton("1/x",SLOT(unaryOperatorClicked()));
    Button*equalBtn=createButton("=",SLOT(equalClicked()));
    Button*changeBtn=createButton("\302\261",SLOT(changeClicked()));//正负号改变的编码

    auto mainLayout=new QGridLayout(this);
    mainLayout->addWidget(display,0,0,1,7);
    mainLayout->addWidget(backspaceBtn,1,0,1,2);
    mainLayout->addWidget(clearBtn,1,2,1,2);
    mainLayout->addWidget(clearAllBtn,1,4,1,3);

    mainLayout->addItem(new QSpacerItem(20,40,QSizePolicy::Expanding),2,0);
    for(int i=1;i<10;i++)
    {
        int row=((9-i)/3)+2;
        int col=((i-1)%3)+1;
        mainLayout->addWidget(digitButtons[i],row,col);
    }

    mainLayout->addWidget(digitButtons[0],5,1);
    mainLayout->addWidget(pointBtn,5,2);
    mainLayout->addWidget(changeBtn,5,3);

    mainLayout->addWidget(divBtn,2,4);
    mainLayout->addWidget(timesBtn,3,4);
    mainLayout->addWidget(minusBtn,4,4);
    mainLayout->addWidget(plusBtn,5,4);

    mainLayout->addWidget(sqrtBtn,2,5);
    mainLayout->addWidget(powerBtn,3,5);
    mainLayout->addWidget(reciprocalBtn,4,5);
    mainLayout->addWidget(equalBtn,5,5);

    mainLayout->addItem(new QSpacerItem(20,40,QSizePolicy::Expanding),3,6);
}

Widget::~Widget() {}

void Widget::digitClicke()
{
    Button*btn=qobject_cast<Button*>(sender());
    int digitValue=btn->text().toInt();
    if(display->text()=="0"&&digitValue==0)
        return;
    if(waitingForOperand)
    {
        display->clear();
        waitingForOperand=false;
    }
    display->setText(display->text()+QString::number(digitValue));
}

void Widget::pointClicked()
{
    if(waitingForOperand)
        display->setText("0");
    if(!display->text().contains('.'))
    {
        display->setText((display->text()+"."));
    }
    waitingForOperand=false;
}

void Widget::backSpaceClicked()
{
    if(waitingForOperand) return;
    QString txt=display->text();
    txt.chop(1);
    if(txt.isEmpty())
    {
        txt="0";
        waitingForOperand=true;
    }
    display->setText(txt);
}

void Widget::clear()
{
    if(waitingForOperand) return;
    display->setText("0");
    waitingForOperand=true;
}

void Widget::clearAll()
{
    sumSofar=0;
    factorSaFar=0;
    pendingAdditiveQperator.clear();
    pendingMultipcativeOperator.clear();
    display->setText("0");
    waitingForOperand=true;
}

void Widget::muliplicativeOperatorClicked()
{
     Button*btn=qobject_cast<Button*>(sender());
    if(!btn) return;
    QString oprator=btn->text();
    double operand=display->text().toDouble();
    if(!pendingMultipcativeOperator.isEmpty())
    {
        if(!calucate(operand,oprator))//计算发生错误
        {
            abortOperator();
            return;
        }
        display->setText(QString::number(factorSaFar));
    }
    else
    {
        factorSaFar=operand;
    }
    pendingMultipcativeOperator=oprator;
    waitingForOperand=true;
}

void Widget::additiveOperatorClicked()
{
    Button*btn=qobject_cast<Button*>(sender());
    QString oprator=btn->text();
    double operand=display->text().toDouble();
    if(!pendingMultipcativeOperator.isEmpty())
    {
        if(!calucate(operand,oprator))
        {
            abortOperator();
            return;
        }
        display->setText(QString::number(factorSaFar));
        operand=factorSaFar;
        factorSaFar=0;
        pendingMultipcativeOperator.clear();
    }

    if(!pendingAdditiveQperator.isEmpty())
    {
        if(!calucate(operand,oprator))
        {
            abortOperator();
            return;
        }
          display->setText(QString::number(factorSaFar));
    }
    else
    {
        sumSofar=operand;
    }
    pendingAdditiveQperator=oprator;
    waitingForOperand=true;
}

void Widget::unaryOperatorClicked()
{
     Button*btn=qobject_cast<Button*>(sender());
    QString oprator=btn->text();
     double operand=display->text().toDouble();
    double result=0;
     if(oprator==("sqrt"))
    {
        if(operand<0)
         {
             abortOperator();
            return;
        }
        result=std::sqrt(operand);
    }
    else if(oprator=="x\302\262")
    {
         result=std::pow(operand,2);
    }
    else if(oprator=="1/x")
    {
        if(operand==0)
        {
            abortOperator();
            return;
        }
        result=1.0/operand;
    }
    display->setText(QString::number(result));
    waitingForOperand=true;
}

void Widget::equalClicked()
{
    double operand=display->text().toDouble();
    if(!pendingMultipcativeOperator.isEmpty())
    {
        if(!calucate(operand,pendingMultipcativeOperator))
        {
            abortOperator();
            return;
        }
        operand=factorSaFar;
        factorSaFar=0;
        pendingMultipcativeOperator.clear();
    }
    if(!pendingAdditiveQperator.isEmpty())
    {
        if(!calucate(operand,pendingAdditiveQperator))
        {
            abortOperator();
            return;
        }
        pendingAdditiveQperator.clear();
    }
    else
    {
        sumSofar=operand;
    }
    display->setText(QString::number(sumSofar));
    sumSofar=0;
    waitingForOperand=true;
}

void Widget::changeClicked()
{
    QString txt=display->text();
    double v=txt.toDouble();
    if(v>0)
    {
        txt.prepend("-");
    }
    else if(v<0)
    {
        txt.remove(0,1);
    }
    display->setText(txt);
}

Button *Widget::createButton(const QString &text, const char *member)
{
    Button*btn=new Button(text);
    connect(btn,SIGNAL(clicked()),this,member);
    return btn;
}

bool Widget::calucate(double rightOperand, const QString &pendingOperator)
{
    if(pendingOperator=="+")
    {
        sumSofar+=rightOperand;
    }
    else if(pendingOperator=="-")
    {
        sumSofar-=rightOperand;
    }
    else if(pendingOperator=="\303\227")
    {
        factorSaFar*=rightOperand;
    }
    else if(pendingOperator=="\303\267")
    {
        if(rightOperand==0.0) return false;
        factorSaFar/=rightOperand;
    }
    return true;
}

void Widget::abortOperator()
{
    clearAll();
    display->setText("######");
}
